package org.terasology.game;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.reflections.Reflections;
import org.terasology.componentSystem.RenderSystem;
import org.terasology.entitySystem.ComponentSystem;
import org.terasology.entitySystem.EntityManager;
import org.terasology.entitySystem.EventHandlerSystem;
import org.terasology.entitySystem.RegisterComponentSystem;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
* Simple manager for component systems.
* This is an initial, rough implementation to be improved later.
*
* @author Immortius <immortius@gmail.com>
*/
public class ComponentSystemManager {
private Logger logger = Logger.getLogger(getClass().getName());
private Map<String, ComponentSystem> namedLookup = Maps.newHashMap();
private List<RenderSystem> renderSubscribers = Lists.newArrayList();
private List<ComponentSystem> store = Lists.newArrayList();
public ComponentSystemManager() {
}
// TODO: Mod support
public void loadEngineSystems() {
loadSystems("engine", "org.terasology.componentSystem");
}
public void loadSystems(String packageName, String rootPackagePath) {
Reflections reflections = new Reflections(rootPackagePath);
Set<Class<?>> systems = reflections.getTypesAnnotatedWith(RegisterComponentSystem.class);
for (Class<?> system : systems) {
if (!ComponentSystem.class.isAssignableFrom(system)) {
logger.log(Level.WARNING, String.format("Cannot load %s, must be a subclass of ComponentSystem", system.getSimpleName()));
continue;
}
RegisterComponentSystem registerInfo = system.getAnnotation(RegisterComponentSystem.class);
// TODO: filter registrations
String id = packageName + ":" + system.getSimpleName();
try {
ComponentSystem newSystem = (ComponentSystem) system.newInstance();
register(newSystem, id);
logger.log(Level.INFO, "Loaded " + id);
} catch (InstantiationException e) {
logger.log(Level.SEVERE, "Failed to load system " + id, e);
} catch (IllegalAccessException e) {
logger.log(Level.SEVERE, "Failed to load system " + id, e);
}
}
}
public <T extends ComponentSystem> void register(ComponentSystem object, String name) {
store.add(object);
if (object instanceof RenderSystem) {
renderSubscribers.add((RenderSystem) object);
}
if (object instanceof EventHandlerSystem) {
CoreRegistry.get(EntityManager.class).getEventSystem().registerEventHandler((EventHandlerSystem) object);
}
namedLookup.put(name, object);
}
// TODO: unregister?
public ComponentSystem get(String name) {
return namedLookup.get(name);
}
public void clear() {
namedLookup.clear();
store.clear();
renderSubscribers.clear();
}
public Iterable<ComponentSystem> iterateAll() {
return store;
}
public Iterable<RenderSystem> iterateRenderSubscribers() {
return renderSubscribers;
}
}